﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Globalization;
using StripeOne.Core.Tools;

namespace StripeOne.Core.Web
{
    public class StripeOneCookie
    {
        #region Attributes
        
        private string _cookieName;
        private string _cookieDomain;
        private string _defaultCookieDomain = HttpContext.Current.Request.Url.Host;
        private string _cookiePath;
        private int _expirationMinutes;
        private Dictionary<string, string> _cookieValues = new Dictionary<string, string>();

        #endregion

        #region Private Methods
        
        private object GetObject(string key)
        {
            HttpCookie httpCookie = HttpContext.Current.Request.Cookies[this._cookieName];
            if (httpCookie == null)
            {
                return string.Empty;
            }
            if (string.IsNullOrEmpty(key))
            {
                return httpCookie.Value;
            }
            return httpCookie.Values[key];
        }

        #endregion

        #region Public Methods
        
        public StripeOneCookie(string cookieName, string cookieDomain = "", string cookiePath = "/", int expirationMinutes = 0)
		{
			this._cookieName = cookieName;
			this._cookieDomain = string.IsNullOrWhiteSpace(cookieDomain) ? _defaultCookieDomain : cookieDomain;
			this._cookiePath = cookiePath;
			this._expirationMinutes = expirationMinutes;
		}

        public void SetValue(string key, object value)
        {
            this._cookieValues[key] = value.ToString();
        }

        public void Save()
        {
            HttpCookie httpCookie = HttpContext.Current.Request.Cookies[this._cookieName];
            if (httpCookie == null)
            {
                httpCookie = new HttpCookie(this._cookieName);
            }
            if (this._cookieDomain.IndexOf(".") >= 0)
            {
                httpCookie.Domain = this._cookieDomain;
            }
            httpCookie.Path = this._cookiePath;
            if (this._expirationMinutes > 0)
            {
                httpCookie.Expires = DateTime.Now.AddMinutes((double)this._expirationMinutes);
            }
            foreach (string current in this._cookieValues.Keys)
            {
                string value = this._cookieValues[current];
                if (string.IsNullOrEmpty(current))
                {
                    httpCookie.Value = value;
                }
                else
                {
                    httpCookie.Values[current] = value;
                }
            }
            HttpContext.Current.Response.AppendCookie(httpCookie);
        }
        
        #endregion

        #region Parsers

        public string GetString(string key)
        {
            return this.GetObject(key).ToString();
        }
        public string GetString(string key, string defaultValue)
        {
            return this.GetObject(key).ToString(defaultValue);
        }
        public byte GetByte(string key)
        {
            return this.GetObject(key).ToByte();
        }
        public byte GetByte(string key, byte defaultValue)
        {
            return this.GetObject(key).ToByte(defaultValue);
        }
        public int GetInt32(string key)
        {
            return this.GetObject(key).ToInt32();
        }
        public int GetInt32(string key, int defaultValue)
        {
            return this.GetObject(key).ToInt32(defaultValue);
        }
        public long GetInt64(string key)
        {
            return this.GetObject(key).ToInt64();
        }
        public long GetInt64(string key, long defaultValue)
        {
            return this.GetObject(key).ToInt64(defaultValue);
        }
        public decimal GetDecimal(string key)
        {
            return this.GetObject(key).ToDecimal();
        }
        public decimal GetDecimal(string key, decimal defaultValue)
        {
            return this.GetObject(key).ToDecimal(defaultValue);
        }
        public decimal GetDecimal(string key, string cultureName)
        {
            return this.GetObject(key).ToDecimal(cultureName);
        }
        public decimal GetDecimal(string key, string cultureName, decimal defaultValue)
        {
            return this.GetObject(key).ToDecimal(cultureName, defaultValue);
        }
        public decimal GetDecimal(string key, CultureInfo cultureInfo)
        {
            return this.GetObject(key).ToDecimal(cultureInfo);
        }
        public decimal GetDecimal(string key, CultureInfo cultureInfo, decimal defaultValue)
        {
            return this.GetObject(key).ToDecimal(cultureInfo, defaultValue);
        }
        public float GetFloat(string key)
        {
            return this.GetObject(key).ToFloat();
        }
        public float GetFloat(string key, float defaultValue)
        {
            return this.GetObject(key).ToFloat(defaultValue);
        }
        public float GetFloat(string key, CultureInfo cultureInfo)
        {
            return this.GetObject(key).ToFloat(cultureInfo);
        }
        public float GetFloat(string key, CultureInfo cultureInfo, float defaultValue)
        {
            return this.GetObject(key).ToFloat(cultureInfo, defaultValue);
        }
        public float GetFloat(string key, string cultureName)
        {
            return this.GetObject(key).ToFloat(cultureName);
        }
        public float GetFloat(string key, string cultureName, float defaultValue)
        {
            return this.GetObject(key).ToFloat(cultureName, defaultValue);
        }
        public double GetDouble(string key)
        {
            return this.GetObject(key).ToDouble();
        }
        public double GetDouble(string key, double defaultValue)
        {
            return this.GetObject(key).ToDouble(defaultValue);
        }
        public double GetDouble(string key, string cultureName)
        {
            return this.GetObject(key).ToDouble(cultureName);
        }
        public double GetDouble(string key, string cultureName, double defaultValue)
        {
            return this.GetObject(key).ToDouble(cultureName, defaultValue);
        }
        public double GetDouble(string key, CultureInfo cultureInfo)
        {
            return this.GetObject(key).ToDouble(cultureInfo);
        }
        public double GetDouble(string key, CultureInfo cultureInfo, double defaultValue)
        {
            return this.GetObject(key).ToDouble(cultureInfo, defaultValue);
        }
        public bool GetBoolean(string key)
        {
            return this.GetObject(key).ToBoolean();
        }
        public bool GetBoolean(string key, bool defaultValue)
        {
            return this.GetObject(key).ToBoolean(defaultValue);
        }
        public DateTime GetDateTime(string key)
        {
            return this.GetObject(key).ToDateTime();
        }
        public DateTime GetDateTime(string key, DateTime defaultValue)
        {
            return this.GetObject(key).ToDateTime(defaultValue);
        }
        public DateTime GetDateTime(string key, string cultureName)
        {
            return this.GetObject(key).ToDateTime(cultureName);
        }
        public DateTime GetDateTime(string key, string cultureName, DateTime defaultValue)
        {
            return this.GetObject(key).ToDateTime(cultureName, defaultValue);
        }
        public DateTime GetDateTime(string key, CultureInfo cultureInfo)
        {
            return this.GetObject(key).ToDateTime(cultureInfo);
        }
        public DateTime GetDateTime(string key, CultureInfo cultureInfo, DateTime defaultValue)
        {
            return this.GetObject(key).ToDateTime(cultureInfo, defaultValue);
        }
        public TimeSpan GetTimeSpan(string key)
        {
            return this.GetObject(key).ToTimeSpan();
        }
        public TimeSpan GetTimeSpan(string key, TimeSpan defaultValue)
        {
            return this.GetObject(key).ToTimeSpan(defaultValue);
        }

        #endregion
    }
}
